package cn.jserv.shutter;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    BluetoothAdapter bluetoothAdapter;

    ListView listView;

    TextView tipView;

    ActivityResultLauncher<Intent> intentActivityResultLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        setContentView(R.layout.activity_main);
        Objects.requireNonNull(getSupportActionBar()).setElevation(0);
        listView = findViewById(R.id.device_list);
        listView.setOnItemClickListener(this);
        tipView = findViewById(R.id.tip_device);
        tipView.setVisibility(View.INVISIBLE);
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setIndeterminate(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage(getString(R.string.searching));
        progressDialog.setCancelable(false);
        deviceList = new ArrayList<>();
        deviceListAdapter = new DeviceListAdapter(MainActivity.this, R.layout.device_item, deviceList);
        listView.setAdapter(deviceListAdapter);
        intentActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == RESULT_OK) {
                initBlueTooth();
            }
        });
        initBlueTooth();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == ACCESS_FINE_LOCATION_REQUEST_CODE) {
            if (grantResults.length > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    initBlueTooth();
                } else {
                    Toast.makeText(this, "您拒绝了位置权限，蓝牙无法使用", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        BluetoothDevice bluetoothDevice = deviceList.get(i);
        Intent intent = new Intent(MainActivity.this, ShutterActivity.class);
        Bundle bundle = new Bundle();
        bundle.putParcelable("device", bluetoothDevice);
        intent.putExtras(bundle);
        startActivity(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (null != menu) {
            if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) {
                try {
                    Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    method.setAccessible(true);
                    method.invoke(menu, true);
                } catch (Exception ex) {
                    Log.e("MENU", ex.getMessage());
                }
            }
        }
        return super.onMenuOpened(featureId, menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.action_search) {
            initBlueTooth();
        } else if (item.getItemId() == R.id.action_about) {
            // TODO: 2022/5/30 0030 展示关于页面
        }
        return super.onOptionsItemSelected(item);
    }

    private void initBlueTooth() {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN
            }, ACCESS_FINE_LOCATION_REQUEST_CODE);
        } else {
            bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (null == bluetoothAdapter || !bluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                intentActivityResultLauncher.launch(enableBtIntent);
            } else {
                scan();
            }
        }
    }

    private void scan() {
        progressDialog.show();
        tipView.setVisibility(View.INVISIBLE);
        listView.setVisibility(View.VISIBLE);
        deviceList.clear();
        deviceListAdapter.notifyDataSetChanged();
        BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        if (null != bluetoothAdapter && bluetoothAdapter.isEnabled()) {
            if (!mScanning) {
                //5S后停止搜索
                handler.postDelayed(() -> {
                    mScanning = false;
                    bluetoothLeScanner.stopScan(scanCallback);
                    progressDialog.dismiss();
                    if (deviceList.size() <= 0) {
                        tipView.setVisibility(View.VISIBLE);
                        listView.setVisibility(View.INVISIBLE);
                    } else {
                        listView.setVisibility(View.VISIBLE);
                        tipView.setVisibility(View.INVISIBLE);
                    }
                }, 1500);
                mScanning = true;
                bluetoothLeScanner.startScan(scanCallback);
            } else {
                mScanning = false;
                bluetoothLeScanner.stopScan(scanCallback);
                progressDialog.dismiss();
                if (deviceList.size() <= 0) {
                    tipView.setVisibility(View.VISIBLE);
                    listView.setVisibility(View.INVISIBLE);
                } else {
                    listView.setVisibility(View.VISIBLE);
                    tipView.setVisibility(View.INVISIBLE);
                }
            }
        }
    }

    private final ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            if (null != device.getName() && device.getName().contains("Shutter") && !deviceList.contains(device)) {
                deviceList.add(device);
            }
            deviceListAdapter.notifyDataSetChanged();
        }
    };

    private boolean mScanning;

    private final Handler handler = new Handler();

    private DeviceListAdapter deviceListAdapter;

    private List<BluetoothDevice> deviceList;

    private static final int ACCESS_FINE_LOCATION_REQUEST_CODE = 0x11;

    ProgressDialog progressDialog;

}